
#include "SipClnTransaction.hpp"
#include "SipUserAgent.hpp"

namespace wtsip{

CSipClnTransaction::CSipClnTransaction(SipMessage& request, CSipUserAgent& ua): 
m_request(request),
m_ua(ua),
m_tid(request.getTransactionId()),
m_callback(0),
m_mth(request.method()),
m_State(ClnInitial)
{}

CSipClnTransaction::~CSipClnTransaction(){
    if (m_callback){
        m_callback->onDestroy(*this);
    }
}


bool CSipClnTransaction::processIncoming(SipMessage* msg){
    if (!msg)
        return false;

    assert(m_mth == msg->method());
    assert(msg->isResponse());

    int hCode = msg->header(h_StatusLine).responseCode() / 100;
    if (1 == hCode){
        if (ClnCompleted == m_State || ClnFailed == m_State){
            return false;
        }
        if (ClnInitial == m_State){
            setState(ClnProvisional);
            if (m_callback){
                m_callback->onResponse(*this, *msg);
            }
        }
    } else if (2 == hCode){
        if (ClnFailed == m_State){
            return false;
        }
        if (ClnInitial == m_State || ClnProvisional == m_State){
            setState(ClnCompleted);
            if (m_callback){
                m_callback->onResponse(*this, *msg);
            }
        }
    } else if (4 == hCode){
        if (ClnCompleted == m_State){
            return false;
        }
        if (ClnInitial == m_State || ClnProvisional == m_State){
            setState(ClnFailed);
            if (m_callback){
                m_callback->onResponse(*this, *msg);
            }
        }
    }
    return true;
}


bool CSipClnTransaction::processTimeOut(ApplicationMessage* msg)
{
    return true;
}


bool CSipClnTransaction::send(std::auto_ptr<SipMessage> msg){
    if (msg.get() && msg->isRequest()){
        /*if (m_callback){
            m_callback->onRequest(*this, *msg);
        }*/
        m_ua.send(msg);
    }
    return true;
}

bool CSipClnTransaction::registerCallback(CSipClnTransactionCallback* callback){
    m_callback = callback;
    return true;
}


bool CSipClnTransaction::unregisterCallback(){
    m_callback = NULL;
    return true;
}


bool CSipClnTransaction::bindDialog(CSipDialogBase* dialog){
    m_bindDialog = dialog;
    return true;
}


SipMessage& CSipClnTransaction::getRequest(){
    return m_request;
}


resip::Data& CSipClnTransaction::getTid(){
    return m_tid;
}


CSipDialogBase* CSipClnTransaction::getBindDlg(){
    return m_bindDialog;
}


bool CSipClnTransaction::setState(int state){
    m_State = state;
    return true;
}


}//namespace


